#include "MainFrame/SettingDock/PaletteDock.h"
#include "MainFrame/SettingDock/PaletteDock/PaletteLabel.h"
#include <QBoxLayout>
#include <QButtonGroup>
#include <QToolButton>
#include <QPixmap>
#include <QEvent>
#include <QRadioButton>
#include <QSlider>
#include <QLineEdit>

#include "IRIVIAPalette.h"

PaletteDock::PaletteDock(const QString &title, QWidget *parent, Qt::WindowFlags flags):
    QDockWidget(title, parent, flags),
    m_pWidget(nullptr),
    m_pForeBackWidget(nullptr),
    m_pPaletteWidget(nullptr),
    m_pRGBWidget(nullptr),
    m_pMainPaletteLabel(nullptr),
    m_pSidePaletteLabel(nullptr),
    m_pForegroundRadioButton(nullptr),
    m_pBackgroundRadioButton(nullptr),
    m_pForeBackButtonGroup(nullptr),
    m_pForegroundColorButton(nullptr),
    m_pBackgroundColorButton(nullptr),
    m_pRRadioButton(nullptr),
    m_pGRadioButton(nullptr),
    m_pBRadioButton(nullptr),
    m_pRSlider(nullptr),
    m_pGSlider(nullptr),
    m_pBSlider(nullptr),
    m_pRLineEdit(nullptr),
    m_pGLineEdit(nullptr),
    m_pBLineEdit(nullptr),
    m_pRGBButtonGroup(nullptr),
    m_nCurR(0),
    m_nCurG(0),
    m_nCurB(0),
    m_nCurChannel(0)
{
    setFeatures(DockWidgetFloatable | DockWidgetMovable);
    this->setMinimumWidth(250);
    this->setMaximumWidth(500);
    this->setMaximumHeight(480);
    initSettingWidget();
    connetSignalToSlots();
}

PaletteDock::~PaletteDock()
{

}

void PaletteDock::initSettingWidget()
{
    m_pWidget = new QWidget;
    this->setWidget(m_pWidget);

    QVBoxLayout *widgetlay = new QVBoxLayout(m_pWidget);
    m_pWidget->setLayout(widgetlay);

    m_pForeBackWidget = new QWidget(m_pWidget);
    m_pPaletteWidget = new QWidget(m_pWidget);
    m_pRGBWidget = new QWidget(m_pWidget);
    widgetlay->addWidget(m_pForeBackWidget);
    widgetlay->addWidget(m_pPaletteWidget);
    widgetlay->addWidget(m_pRGBWidget);

    initForeBackWidget();
    initPaletteWidget();
    initRGBWidget();

}

void PaletteDock::initForeBackWidget()
{
    QHBoxLayout* forebacklay = new QHBoxLayout;
    m_pForeBackWidget->setLayout(forebacklay);

    m_pForegroundRadioButton = new QRadioButton("Foreground", m_pForeBackWidget);
    m_pForegroundRadioButton->setChecked(true);
    m_pBackgroundRadioButton = new QRadioButton("Background", m_pForeBackWidget);

    m_pForegroundColorButton = new QToolButton(m_pForeBackWidget);
    m_pForegroundColorButton->setFixedSize(80, 30);
    setButtonColor(m_pForegroundColorButton, 0, 0, 0);

    m_pBackgroundColorButton = new QToolButton(m_pForeBackWidget);
    m_pBackgroundColorButton->setFixedSize(80, 30);
    setButtonColor(m_pBackgroundColorButton, 255, 255, 255);

    forebacklay->addWidget(m_pForegroundRadioButton);
    forebacklay->addWidget(m_pForegroundColorButton);
    forebacklay->addWidget(m_pBackgroundRadioButton);
    forebacklay->addWidget(m_pBackgroundColorButton);

    m_pForeBackButtonGroup = new QButtonGroup();
    m_pForeBackButtonGroup->addButton(m_pForegroundRadioButton, 0);
    m_pForeBackButtonGroup->addButton(m_pBackgroundRadioButton, 1);
}

void PaletteDock::initPaletteWidget()
{
    QHBoxLayout *palelay = new QHBoxLayout(m_pPaletteWidget);
    m_pPaletteWidget->setLayout(palelay);

    m_pMainPaletteLabel = new PaletteLabel(m_pPaletteWidget);
    m_pMainPaletteLabel->setFixedSize(256, 256);
    m_pSidePaletteLabel = new PaletteLabel(m_pPaletteWidget);
    m_pSidePaletteLabel->setFixedSize(30 , 256);

    palelay->addWidget(m_pMainPaletteLabel);
    palelay->addWidget(m_pSidePaletteLabel);
    //init
    IRIVIAPalette().setMainPalette(0, 0);
    IRIVIAPalette().setSidePalette(0);
    m_pMainPaletteLabel->setPixmap(QPixmap::fromImage(IRIVIAPalette().getMainQImage()));
    m_pSidePaletteLabel->setPixmap(QPixmap::fromImage(IRIVIAPalette().getSideQImage()));
}

void PaletteDock::initRGBWidget()
{
    QGridLayout* rgblay = new QGridLayout(m_pRGBWidget);
    m_pRGBWidget->setLayout(rgblay);

    m_pRRadioButton = new QRadioButton("R", m_pRGBWidget);
    m_pRRadioButton->setChecked(true);
    m_pGRadioButton = new QRadioButton("G", m_pRGBWidget);
    m_pBRadioButton = new QRadioButton("B", m_pRGBWidget);

    m_pRSlider = new QSlider(Qt::Horizontal, m_pRGBWidget);
    m_pRSlider->setRange(0, 255);
    m_pGSlider = new QSlider(Qt::Horizontal, m_pRGBWidget);
    m_pGSlider->setRange(0, 255);
    m_pBSlider = new QSlider(Qt::Horizontal, m_pRGBWidget);
    m_pBSlider->setRange(0, 255);

    m_pRLineEdit = new QLineEdit("0", m_pRGBWidget);
    m_pRLineEdit->setMaximumWidth(30);
    m_pGLineEdit = new QLineEdit("0", m_pRGBWidget);
    m_pGLineEdit->setMaximumWidth(30);
    m_pBLineEdit = new QLineEdit("0", m_pRGBWidget);
    m_pBLineEdit->setMaximumWidth(30);

    rgblay->addWidget(m_pRRadioButton,  0, 0, 1, 1);
    rgblay->addWidget(m_pRSlider,       0, 1, 1, 6);
    rgblay->addWidget(m_pRLineEdit,     0, 7, 1, 1);
    rgblay->addWidget(m_pGRadioButton,  1, 0, 1, 1);
    rgblay->addWidget(m_pGSlider,       1, 1, 1, 6);
    rgblay->addWidget(m_pGLineEdit,     1, 7, 1, 1);
    rgblay->addWidget(m_pBRadioButton,  2, 0, 1, 1);
    rgblay->addWidget(m_pBSlider,       2, 1, 1, 6);
    rgblay->addWidget(m_pBLineEdit,     2, 7, 1, 1);

    m_pRGBButtonGroup = new QButtonGroup();
    m_pRGBButtonGroup->addButton(m_pRRadioButton, 0);
    m_pRGBButtonGroup->addButton(m_pGRadioButton, 1);
    m_pRGBButtonGroup->addButton(m_pBRadioButton, 2);
}

void PaletteDock::connetSignalToSlots()
{
    connect(m_pForeBackButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(onForeBackChanged(int)));

    connect(m_pRGBButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(onChannelChanged(int)));

    connect(m_pRSlider, SIGNAL(valueChanged(int)), this, SLOT(onRChanged(int)));
    connect(m_pGSlider, SIGNAL(valueChanged(int)), this, SLOT(onGChanged(int)));
    connect(m_pBSlider, SIGNAL(valueChanged(int)), this, SLOT(onBChanged(int)));

    connect(m_pRLineEdit, SIGNAL(editingFinished()), this, SLOT(onRLineEdited()));
    connect(m_pGLineEdit, SIGNAL(editingFinished()), this, SLOT(onGLineEdited()));
    connect(m_pBLineEdit, SIGNAL(editingFinished()), this, SLOT(onBLineEdited()));

    connect(m_pMainPaletteLabel, SIGNAL(CursorPosChanged(QPoint)),
            this, SLOT(onMainLabelCursorChanged(QPoint)));
    connect(m_pSidePaletteLabel, SIGNAL(CursorPosChanged(QPoint)),
            this, SLOT(onSideLabelCursorChanged(QPoint)));


    connect(this, SIGNAL(RGBChannelChanged(int, int, int, int)),
            this, SLOT(onRGBChannelChanged(int, int, int, int)));
}

void PaletteDock::initTrans()
{
    m_pForegroundRadioButton->setText(tr("Foreground"));
    m_pBackgroundRadioButton->setText(tr("Background"));
}

void PaletteDock::setButtonColor(QToolButton *button, int r, int g, int b)
{
    button->setStyleSheet("QToolButton{"
                          "background: rgb("+ QString::number(r) + ", " + QString::number(g) + ", " + QString::number(b) + ");"
                                                                                                                           "border: 0px;"
                                                                                                                           "}");
}

void PaletteDock::onForeBackChanged(int i)
{
    QVector<int> color;
    switch(i)
    {
    case 0:
        color = IRIVIAPalette().getCurColor();
        break;
    case 1:
        color = IRIVIAPalette().getCurBackColor();
        break;
    }
    m_pRSlider->setValue(color[0]);
    m_pGSlider->setValue(color[1]);
    m_pBSlider->setValue(color[2]);
}

void PaletteDock::onChannelChanged(int channel)
{
    m_nCurChannel = channel;
    emit RGBChannelChanged(m_nCurChannel, m_nCurR, m_nCurG, m_nCurB);
}

void PaletteDock::onRChanged(int r)
{
    m_nCurR = r;
    m_pRSlider->setValue(r);
    m_pRLineEdit->setText(QString::number(r));
    emit RGBChannelChanged(m_nCurChannel, m_nCurR, m_nCurG, m_nCurB);
}

void PaletteDock::onGChanged(int g)
{
    m_nCurG = g;
    m_pGSlider->setValue(g);
    m_pGLineEdit->setText(QString::number(g));
    emit RGBChannelChanged(m_nCurChannel, m_nCurR, m_nCurG, m_nCurB);
}

void PaletteDock::onBChanged(int b)
{
    m_nCurB = b;
    m_pBSlider->setValue(b);
    m_pBLineEdit->setText(QString::number(b));
    emit RGBChannelChanged(m_nCurChannel, m_nCurR, m_nCurG, m_nCurB);
}

void PaletteDock::onRGBChannelChanged(int channel, int RDegree, int GDegree, int BDegree)
{
    switch(m_pForeBackButtonGroup->checkedId())
    {
    case 0: //foreground color
        setButtonColor(m_pForegroundColorButton, RDegree, GDegree, BDegree);
        IRIVIAPalette().setCurColor(RDegree, GDegree, BDegree);
        break;
    case 1: //background color
        setButtonColor(m_pBackgroundColorButton, RDegree, GDegree, BDegree);
        IRIVIAPalette().setCurBackColor(RDegree, GDegree, BDegree);
        break;
    }

    int degree = -1;
    switch(channel)
    {
    case 0: degree = RDegree;   break;
    case 1: degree = GDegree;   break;
    case 2: degree = BDegree;   break;
    }
    IRIVIAPalette().setMainPalette(channel, degree);
    IRIVIAPalette().setSidePalette(channel);
    m_pMainPaletteLabel->setPixmap(QPixmap::fromImage(IRIVIAPalette().getMainQImage()));
    m_pSidePaletteLabel->setPixmap(QPixmap::fromImage(IRIVIAPalette().getSideQImage()));
}

void PaletteDock::onRLineEdited()
{
    m_pRSlider->setValue(m_pRLineEdit->text().toInt());
}

void PaletteDock::onGLineEdited()
{
    m_pGSlider->setValue(m_pGLineEdit->text().toInt());
}

void PaletteDock::onBLineEdited()
{
    m_pBSlider->setValue(m_pBLineEdit->text().toInt());
}

void PaletteDock::onMainLabelCursorChanged(const QPoint &p)
{
    int x = p.x();
    int y = p.y();
    switch(m_nCurChannel)
    {
    case 0:
        m_pBSlider->setValue(x);
        m_pGSlider->setValue(y);
        break;
    case 1:
        m_pBSlider->setValue(x);
        m_pRSlider->setValue(y);
        break;
    case 2:
        m_pGSlider->setValue(x);
        m_pRSlider->setValue(y);
        break;
    }
}

void PaletteDock::onSideLabelCursorChanged(const QPoint &p)
{
    int y = p.y();
    switch(m_nCurChannel)
    {
    case 0:
        m_pRSlider->setValue(y);
        break;
    case 1:
        m_pGSlider->setValue(y);
        break;
    case 2:
        m_pBSlider->setValue(y);
        break;
    }
}

